// jdataview.h copyright 2007 cycling '74 all rights reserved


#ifndef _JDATAVIEW_H_
#define _JDATAVIEW_H_

// symbols used 

BEGIN_USING_C_LINKAGE

extern t_symbol *ps_jdv_update;

// a jdataview has columns

// constants

#define JDATAVIEW_CELLMAX MAX_PATH_CHARS	// maximum number of chars in a cell, do not try to write more than 
											// this number to the text buffer supplied by the 'getcelltext' functions

#define JCOLUMN_DEFAULT_WIDTH 50
#define JCOLUMN_DEFAULT_MINWIDTH 50
#define JCOLUMN_DEFAULT_MAXWIDTH 100

#define JCOLUMN_DEFAULT_FONTSIZE 10

#define JCOLUMN_DEFAULT_MAXTEXTLEN 256

// values for c_alignment

enum {
	JCOLUMN_ALIGN_LEFT = 1,
	JCOLUMN_ALIGN_CENTER,
	JCOLUMN_ALIGN_RIGHT
};

enum {
	JCOLUMN_STYLE_PLAIN = 0,
	JCOLUMN_STYLE_BOLD = 1,
	JCOLUMN_STYLE_ITALIC = 2
};

enum {
	JCOLUMN_MOUSE_ENTER = 0,
	JCOLUMN_MOUSE_MOVE = 1,
	JCOLUMN_MOUSE_EXIT = 2
};

enum {
	JCOLUMN_SORTDIRECTION_FORWARD = 1,
	JCOLUMN_SORTDIRECTION_BACKWARD = 0
};

enum {
	JCOLUMN_INITIALLYSORTED_NONE = 0,
	JCOLUMN_INITIALLYSORTED_FORWARDS = 1,
	JCOLUMN_INITIALLYSORTED_BACKWARDS = 2
};

// kinds of JUCE component style columns (or cells within columns)

enum {
	JCOLUMN_COMPONENT_NONE = 0,
	JCOLUMN_COMPONENT_CHECKBOX = 1,
	JCOLUMN_COMPONENT_TEXTEDITOR = 2,		// eventually alphanumeric and numeric variants
	JCOLUMN_COMPONENT_SLIDER = 3,
	JCOLUMN_COMPONENT_COLOR = 4,
	JCOLUMN_COMPONENT_MENU = 5
};

enum {
	JCOLUMN_MENU_INDEX = 1,					// report index chosen instead of value of item
	JCOLUMN_MENU_FONTMENU = 2,				// flag for showing a font menu
	JCOLUMN_MENU_PAINT = 4,					// cell is drawn with client paint method
	JCOLUMN_MENU_SELECT = 8,					// row is selected on mouse down
	JCOLUMN_MENU_NOPANEL = 16,				// for font menu, don't include the show fonts item
	JCOLUMN_MENU_CLEARITEM = 32				// for font menu, include a clear item
};

enum {
	JCOLUMN_TEXT_ONESYMBOL = 1,
	JCOLUMN_TEXT_COMMASEPARATED = 2,
	JCOLUMN_TEXT_ICON = 4,
	JCOLUMN_TEXT_HASBUTTON = 8,
	JCOLUMN_TEXT_FILECHOOSEBUTTON = 16,
	JCOLUMN_TEXT_VIEWBUTTON = 32,
	JCOLUMN_TEXT_EDITBUTTON = 64,
	JCOLUMN_TEXT_TIME = 128,
	JCOLUMN_TEXT_FLOAT = 256,
	JCOLUMN_TEXT_INT = 512,
	JCOLUMN_TEXT_CANTEDIT = 1024,
	JCOLUMN_TEXT_FONTSIZE = 2048
};

enum {
	JCOLUMN_SLIDER_NOTEXTBOX = 1,
	JCOLUMN_SLIDER_ZERO_TO_ONE = 2
};

#define JCOLUMN_DISABLED 0x1000

typedef struct _celldesc
{
	long row;
	long col;
	long data;
} t_celldesc;

typedef struct _col
{
	t_object c_obj;
	void *obex;
	t_symbol *c_name;			// column name (hash)
	t_object *c_dv;				// parent dataview
	int c_id;					// id in DataViewComponent
	long c_width;				// column width in pixels
	long c_maxwidth;			// max column width
	long c_minwidth;			// min column width
	char c_autosize;			// determine width of text column automatically (true/false)
	char c_alignment;			// display of text, left, right, center
	t_symbol *c_font;			// name of font
	long c_fontsize;			// font size (points?)
	t_symbol *c_label;			// heading of column
	char c_separator;			// separator mode
	char c_button;				// column has a button (true/false)
	t_symbol *c_buttonlabel;	// text in a button
	t_symbol *c_customsort;		// message sent to sort this column -- if none, default sorting is used based on value c_numeric
	char c_overridesort;		// if true only the sortdata method is called, not the sort method (true/false)
	t_symbol *c_custompaint;	// send this msg name to client to paint this column
	t_symbol *c_valuemsg;		// message sent when a component mode cell's value changes
	t_symbol *c_beginmsg;		// message sent when a component mode cell's value is about to start changing
	t_symbol *c_endmsg;			// message sent when a component mode cell's value is finished changing
	t_symbol *c_rowcomponentmsg;// message sent to determine what kind of component should be created for each cell in a column
	t_symbol *c_custommenuset;	// message to set a menu (for a readonly or custompaint column)
	t_symbol *c_custommenuresult;	// message sent when an item is chosen from a custom menu
	char c_editable;			// can you edit the data in a cell in this column
	char c_selectable;			// can select the data in a cell in this column (possibly without being able to edit)
	char c_multiselectable;		// can you select more than one cell in this column
	char c_sortable;			// can you click on a column heading to sort the data
	long c_initiallysorted;		// if this is set to JCOLUMN_INITIALLYSORTED_FORWARDS the column is displayed with the sort triangle
	long c_maxtextlen;			// maximum text length: this is used to allocate a buffer to pass to gettext (but there is also a constant)
	long c_sortdirection;
	long c_component;			// enum of components (check box etc.)
	char c_canselect;			// can select entire column
	char c_cancut;				// can cut/clear entire column
	char c_cancopy;				// can copy entire column
	char c_cancutcells;			// can cut a single cell (assumes "editable" or "selectable") (probably won't be implemented)
	char c_cancopycells;		// can copy a single cell
	char c_canpastecells;		// can paste into a single cell
	char c_hideable;			// can the column be hidden
	char c_hidden;				// is the column hidden (set/get)
	char c_numeric;				// is the data numeric (i.e., is getcellvalue implemented)
	char c_draggable;			// can drag the column to rearrange it
	char c_casesensitive;		// use case sensitive sorting (applies only to default text sorting)
	void *c_reference;			// reference for the use of the client
	double c_indentspacing;		// amount of space (in pixels) for one indent level
	t_symbol *c_insertbefore;	// name of column before which this one should have been inserted (used only once)
	t_symbol *c_cellcluemsg;	// message to send requesting clue text for a cell
	t_symbol *c_celltextcolormsg;	// message to get the cell's text color
	t_symbol *c_celltextstylemsg;	// message to get the cell's style and alignment
} t_jcolumn;

// columns are stored in a hashtab and accessed by name

typedef struct _jdataview
{
	t_object d_obj;
	void *obex;
	t_linklist *d_components;	// list of DataViewComponents showing this dataview
	t_object *d_client;			// object that will be sent messages to get data to display
	t_hashtab *d_columns;		// columns -- point to t_jcolumn objects
	t_hashtab *d_id2columns;	// columns from column IDs
	t_linklist *d_colorder;		// current order of columns
	t_indexmap *d_rowmap;		// collection of rows (including number of rows)
	long d_numcols;				// number of columns
	double d_rowheight;			// fixed height of a row in pixels
	char d_autoheight;			// height determined by font
	char d_hierarchical;		// does it allow hierarchical disclosure (true / false) -- not implemented yet
	t_jrgba d_rowcolor1;		// odd row color (striped)
	t_jrgba d_rowcolor2;		// even row color
	t_jrgba d_selectcolor;		// color when rows are selected
	t_jrgba d_bordercolor;		// border color
	char d_bordercolorset;		// was border color set? if not, use JUCE default
	char d_canselectmultiple;	// multiple rows are selectable
	char d_cancopy;				// copy enabled
	char d_cancut;				// cut / clear enabled
	char d_canpaste;			// paste enabled
	char d_canrearrangerows;		// rows can be dragged to rearrange -- may not be implemented yet
	char d_canrearrangecolumns;	// columns can be dragged to rearrange
	long d_viscount;			// number of visible views of this dataview
	long d_inset;				// inset for table inside containing component in pixels
	char d_autosizeright;		// right side autosizes when top-level component changes
	char d_autosizebottom;		// bottom autosizes when top-level component changes
	char d_dragenabled;			// enabled for dragging (as in drag and drop)
	t_symbol *d_fontname;		// font name
	double d_fontsize;			// font size
	t_symbol *d_colheadercluemsg;	// message to send requesting clue text for the column headers
	char d_autosizerightcolumn;	// right column should stretch to remaining width of the dataview, regardless of column width
	char d_customselectcolor;		// send getcellcolor message to draw selected cell, don't use select color
	void *d_qelem;				// defer updating
	double d_colheaderheight;
	char d_drawgrid;
	long d_top_inset;			// vertical inset for row background (default 0)
	long d_bottom_inset;		// vertical inset for row background (default 0)
	long d_borderthickness;		// border line thickness default 0 for no border
	char d_keyfocusable;		// notify component to grab some keys
	char d_enabledeletekey;		// delete key will delete selected rows
	char d_usegradient;			// color rows with gradient between rowcolor1 (top) and rowcolor2 (bottom)
	char d_inchange;			// in change flag for inspector end-change protection system
	char d_horizscrollvisible;	// is horizontal scroll bar visible
	char d_vertscrollvisible;	// is vertical scroll bar visible
	char d_scrollvisset;		// has the scroll visibility ever been changed since the dv was created?
	char d_overridefocus;		// override default focus behavior where ListBox is focused when assigning focus to the dataview
	char d_usesystemfont;		// use system font (true by default)
	t_object *d_searchcolumn;	// column we ask for celltext in order to navigate the selection via the keyboard
	t_object *d_returnkeycolumn;// column that is sent the return key when a given row is selected
	void *d_navcache;			// sorted list of column strings for key navigation
	char d_usecharheight;		// use font specified in points rather than pixels (default is pixels)
} t_jdataview;

// used to notify a component of a jdataview change

typedef struct _jdv_notifier
{
	t_jdataview *n_dataview;
	t_symbol *n_what;
	void *n_data;
} t_jdv_notifier;


// used to pass data to a client sort function

typedef struct _privatesortrec
{
	t_jcolumn *p_col;		// column object to sort
	char p_fwd;				// 1 if sorting "forwards"
	t_object *p_client;
	t_jdataview *p_dv;
} t_privatesortrec;


// functions

void jdataview_initclass(void);

// create one

void *jdataview_new(void);

// set its client

void jdataview_setclient(t_object *dv, t_object *client);
t_object *jdataview_getclient(t_object *dv);

// make it visible

void jdataview_patchervis(t_object *dv, t_object *pv);
void jdataview_patcherinvis(t_object *dv, t_object *pv);

// set global attributes

void jdataview_setheight(t_object *dv, long height);
long jdataview_getheight(t_object *dv);

void jdataview_setautoheight(t_object *dv, long way);
short jdataview_getautoheight(t_object *dv);

void jdataview_setcolumnheaderheight(t_object *dv, double height);
double jdataview_getcolumnheaderheight(t_object *dv);

void jdataview_setrowcolor1(t_object *dv, t_jrgba *c);
void jdataview_getrowcolor1(t_object *dv, t_jrgba *c);
void jdataview_setrowcolor2(t_object *dv, t_jrgba *c);
void jdataview_getrowcolor2(t_object *dv, t_jrgba *c);

void jdataview_getselectcolor(t_object *dv, t_jrgba *c);
void jdataview_setselectcolor(t_object *dv, t_jrgba *c);

void jdataview_setusegradient(t_object *dv, long way);
long jdataview_getusegradient(t_object *dv);

void jdataview_setcanselectmultiple(t_object *dv, long way);
short jdataview_getcanselectmultiple(t_object *dv);

void jdataview_setcancopy(t_object *dv, long way);
short jdataview_getcancopy(t_object *dv);

void jdataview_setcanpaste(t_object *dv, long way);
short jdataview_getcanpaste(t_object *dv);

void jdataview_setinset(t_object *dv, long inset);
long jdataview_getinset(t_object *dv);

void jdataview_setautosizeright(t_object *dv, long way);
long jdataview_getautosizeright(t_object *dv);

void jdataview_setautosizebottom(t_object *dv, long way);
long jdataview_getautosizebottom(t_object *dv);

void jdataview_setautosizerightcolumn(t_object *dv, long way);
long jdataview_getautosizerightcolumn(t_object *dv);

void jdataview_setusecharheightfont(t_object *dv, long way);

// standard containersizechange method for objects to use
// i.e., class_addmethod(c, jdataview_containersizechange, "containersizechange", A_CANT, 0);

long jdataview_containersizechange(t_object *x, double cw, double ch, double *width, double *height, int asr, int asb);

t_max_err jdataview_gethorizscrollvalues(t_object *x, double *min, double *max, double *start, double *size);
void jdataview_sethorizscrollvalues(t_object *x, double start, double size);

t_max_err jdataview_getvertscrollvalues(t_object *x, double *min, double *max, double *start, double *size);
void jdataview_setvertscrollvalues(t_object *x, double start, double size);

t_max_err jdataview_setscrollvisible(t_object *x, long vbar, long hbar);

void jdataview_setborderthickness(t_object *dv, long val);
long jdataview_getborderthickness(t_object *dv);

void jdataview_setkeyfocusable(t_object *x, long val);
long jdataview_getkeyfocusable(t_object *x);

void jdataview_setenabledeletekey(t_object *dv, long way); 
long jdataview_getenabledeletekey(t_object *dv); 

void jdataview_setfontname(t_object *dv, t_symbol *fontname);
t_symbol *jdataview_getfontname(t_object *dv);
void jdataview_setfontsize(t_object *dv, double fsize);
double jdataview_getfontsize(t_object *dv);

double jdataview_getclientfontsize(t_object *dv);

void jdataview_columnheadermouse(t_object *dv, t_object *col, long msg);

int jdataview_getdragenabled(t_object *dv);
void jdataview_setdragenabled(t_object *dv, long way);

void jdataview_setcolumnheadercluemsg(t_object *dv, t_symbol *msg);
t_symbol *jdataview_getcolumnheadercluemsg(t_object *dv);

int jdataview_getdrawgrid(t_object *dv);
void jdataview_setdrawgrid(t_object *dv, int way);
void jdataview_setrowinset(t_object *dv, long top, long bottom);
void jdataview_getrowinset(t_object *dv, long *top, long *bottom);

t_object *jdataview_getsearchcolumn(t_object *dv);
void jdataview_setsearchcolumn(t_object *dv, t_object *col);
void jdataview_setoverridefocus(t_object *dv, long way);
long jdataview_getoverridefocus(t_object *dv);

void jdataview_setreturnkeycolumn(t_object *dv, t_object *col);
t_object *jdataview_getreturnkeycolumn(t_object *dv);

int jdataview_keynavigate(t_object *dv, char *buffer);

// columns access

t_object *jdataview_addcolumn(t_object *dv, t_symbol *name, t_symbol *before, short unused);
t_object *jdataview_addcolumn_hidden(t_object *dv, t_symbol *name, t_symbol *before, short unused);
void *jcolumn_new(void);
void jcolumn_setdataview(t_object *c, t_object *dv);

void jdataview_colname_delete(t_object *dv, t_symbol *name);
void jdataview_deletecolumn(t_object *dv, t_object *col);
t_object *jdataview_getnamedcolumn(t_object *dv, t_symbol *name);
t_object *jdataview_getnthcolumn(t_object *dv, long index);
void jdataview_colname_setvisible(t_object *dv, t_symbol *name, long way);
short jdataview_colname_getvisible(t_object *dv, t_symbol *name);
int jdataview_getnumcolumns(t_object *dv);

// column

int jcolumn_getwidth(t_object *col);
void jcolumn_setwidth(t_object *col, long width);
int jcolumn_getmaxwidth(t_object *col);
void jcolumn_setmaxwidth(t_object *col, long width);
int jcolumn_getminwidth(t_object *col);
void jcolumn_setminwidth(t_object *col, long width);
long jcolumn_getid(t_object *col);
int jcolumn_getautosize(t_object *col);
void jcolumn_setdataview(t_object *col, t_object *dv);
t_symbol *jcolumn_getname(t_object *col);
void jcolumn_setname(t_object *col, t_symbol *name);
void jcolumn_setlabel(t_object *col, t_symbol *label);
t_symbol *jcolumn_getlabel(t_object *col);
void jcolumn_setinsertbefore(t_object *col, t_symbol *before);
t_symbol *jcolumn_getinsertbefore(t_object *col);
void jcolumn_setnumeric(t_object *col, long way);
int jcolumn_getnumeric(t_object *col);
void jcolumn_setcustomsort(t_object *col, t_symbol *msg);
t_symbol *jcolumn_getcustomsort(t_object *col);
void jcolumn_setoverridesort(t_object *col, char val);
char jcolumn_getoverridesort(t_object *col);
void jcolumn_setcustompaint(t_object *col, t_symbol *msg);
t_symbol *jcolumn_getcustompaint(t_object *col);
void jcolumn_setcustommenu(t_object *col, t_symbol *setmsg, t_symbol *resultmsg);
t_symbol *jcolumn_getcustommenu_setmsg(t_object *col);
t_symbol *jcolumn_getcustommenu_resultmsg(t_object *col);
void jcolumn_setsortable(t_object *col, long way);
int jcolumn_getsortable(t_object *col);
void jcolumn_setdraggable(t_object *col, long way);
int jcolumn_getdraggable(t_object *col);
void jcolumn_setinitiallysorted(t_object *col, long way);
int jcolumn_getinitiallysorted(t_object *col);
void jcolumn_sethideable(t_object *col, long way);
int jcolumn_gethideable(t_object *col);
void jcolumn_setvisible(t_object *col, long way);
int jcolumn_getvisible(t_object *col);
void jcolumn_setcasesensitive(t_object *col, long way);
int jcolumn_getcasesensitive(t_object *col);
void jcolumn_setreference(t_object *col, void *ref);
void *jcolumn_getreference(t_object *col);
void jcolumn_setcheckbox(t_object *col, t_symbol *msg);
void jcolumn_setvaluemsg(t_object *col, t_symbol *msg, t_symbol *beginmsg, t_symbol *endmsg);
t_symbol *jcolumn_getvaluemsg(t_object *col);
t_symbol *jcolumn_getbeginchangemsg(t_object *col);
t_symbol *jcolumn_getendchangemsg(t_object *col);
int jcolumn_getcomponent(t_object *col);
void jcolumn_setrowcomponentmsg(t_object *col, t_symbol *msg);
t_symbol *jcolumn_getrowcomponentmsg(t_object *col);
double jcolumn_getindentspacing(t_object *col);
void jcolumn_setindentspacing(t_object *col, double spacing);

void jcolumn_setcellcluemsg(t_object *col, t_symbol *msg);
t_symbol *jcolumn_getcellcluemsg(t_object *col);
t_symbol *jcolumn_getcelltextcolormsg(t_object *col);
void jcolumn_setcelltextcolormsg(t_object *col, t_symbol *msg);
t_symbol *jcolumn_getcelltextstylemsg(t_object *col);
void jcolumn_setcelltextstylemsg(t_object *col, t_symbol *msg);

// visual update of a change to a column

void jcolumn_update(t_object *col, t_symbol *msg);

// define a column based on a dictionary

t_object *jdataview_addcolumnfromdictionary(t_object *dv, t_object *d);

// adding rows

// a row reference is a way of distinguishing a row to the owning object. This is up to the object whose data is being displayed.
// for example, it could be a pointer to an entry in a database
// or if you are displaying attributes it could be a symbol

typedef void *t_rowref;

void jdataview_addrow(t_object *dv, t_rowref rr);
void jdataview_addrows(t_object *dv, long count, t_rowref *rrs);
void jdataview_deleterow(t_object *dv, t_rowref rr);
void jdataview_deleterows(t_object *dv, long count, t_rowref *rrs);
void jdataview_deleteselectedrows(t_object *dv); 
void jdataview_clear(t_object *dv);
int jdataview_getnumrows(t_object *dv);
void jdataview_gettextinrows(t_object *dv, t_rowref *rows, char *cellsep, char **text);
int jdataview_selectedrowcount(t_object *dv);
t_rowref *jdataview_getallrows(t_object *dv);
t_rowref *jdataview_getselectedrows(t_object *dv);
void jdataview_applytoselectedrows(t_object *dv, t_symbol *msg, long bycell);

void jdataview_enablerow(t_object *dv, t_rowref rr, long way);

void jdataview_selectall(t_object *dv);
void jdataview_selectnone(t_object *dv);

// row and column conversion (used by DataViewComponent mostly)

t_object *jdataview_id2column(t_object *dv, int id);
t_symbol *jdataview_id2colname(t_object *dv, int id);
int jdataview_colname2id(t_object *dv, t_symbol *name);
int jdataview_column2id(t_object *dv, t_object *col);
int jdataview_row2id(t_object *dv, t_rowref rr);
t_rowref jdataview_id2row(t_object *dv, int id);

void jdataview_showrow(t_object *dv, t_rowref rr);

// cells

void jdataview_celldesc(t_jdataview *x, t_symbol *colname, t_rowref rr, t_celldesc *desc);
void jdataview_selectcellinview(t_object *dv, t_object *pv, t_symbol *colname, t_rowref rr);
void jdataview_selectcell(t_object *dv, t_symbol *colname, t_rowref rr);
int jdataview_getcelltextlength(t_object *dv, t_symbol *colname, t_rowref rr, long *length);
int jdataview_getcelltext(t_object *dv, t_symbol *colname, t_rowref rr, char *text, long maxlen);
int jdataview_getcellunits(t_object *dv, t_symbol *colname, t_rowref rr, char *text, long maxlen);
int jdataview_setcellunits(t_object *dv, t_symbol *colname, t_rowref rr, t_symbol *val);
int jdataview_getcellunitsyms(t_object *dv, t_symbol *colname, t_rowref rr, long *argc, t_atom **argv);
int jdataview_getcelldescription(t_object *dv, t_symbol *colname, t_rowref rr, char *text);
int jdataview_getcellvalue(t_object *dv, t_symbol *colname, t_rowref rr, long *argc, t_atom *argv);
void jdataview_getcelltextcolor(t_object *dv, t_symbol *colname, t_rowref rr, t_jrgba *color);
void jdataview_getcelltextstyle(t_object *dv, t_symbol *colname, t_rowref rr, long *style, long *align);
int jdataview_getcellmenu(t_object *dv, t_symbol *colname, t_rowref rr, long *argc, t_atom *argv, char **enabled);
void jdataview_setcellvalue(t_object *dv, t_symbol *colname, t_rowref rr, long argc, t_atom *argv);
void jdataview_editcell(t_object *dv, t_symbol *colname, t_rowref rr);
int jdataview_iscelltextselected(t_object *dv, char justfocused);
void jdataview_cellclear(t_object *dv);
void jdataview_cellcut(t_object *dv);
void jdataview_cellcopy(t_object *dv);
void jdataview_cellpaste(t_object *dv);

int jdataview_getcellcomponent(t_object *dv, int columnId, int rowNumber, long *options);
int jdataview_getcellfiletypes(t_object *dv, t_symbol *colname, t_rowref rr, long *count, long **types, char *alloc);
void jdataview_redrawcell(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_begincellchange(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_endcellchange(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_selected(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_selectedrow(t_object *dv, t_rowref rr);
void jdataview_doubleclick(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_contextualclick(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_getcellicon(t_object *dv, t_symbol *colname, t_rowref rr, t_jsurface **surf);
void jdataview_getrowcolor(t_object *dv, t_rowref rr, long isoddrow, t_jrgba *c);
int jdataview_colorbycell(t_object *dv);
void jdataview_getcellcolor(t_object *dv, t_symbol *colname, t_rowref rr, long isoddrow, t_jrgba *c);
int jdataview_getcustomselectcolor(t_object *dv);
void jdataview_setcustomselectcolor(t_object *dv, int way);
double jdataview_getcellindent(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_cellenter(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_cellexit(t_object *dv, t_symbol *colname, t_rowref rr);

int jdataview_getcelleditable(t_object *dv, t_symbol *colname, t_rowref rr);

long jdataview_getbordercolor(t_object *dv, t_jrgba *c);	// returns non-zero if border color set
void jdataview_setbordercolor(t_object *dv, t_jrgba *c);

long jdataview_getusesystemfont(t_object *dv);
void jdataview_setusesystemfont(t_object *dv, long way);

void jdataview_enablecell(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_forcecellvisible(t_object *x, t_symbol *colname, t_rowref rr);

// DataViewComponent calls this for a custom paint method for a column

void jdataview_clientpaintcell(t_object *dv, t_symbol *msg, t_object *pv, int columnId, int rowNumber, int width, int height, int rowIsSelected);

// custom paint method should be declared as:
// void myobject_paint(t_myobject *x, t_object *patcherview, t_symbol *colname, t_rowref rr, int width, int height, int rowIsSelected)
// to obtain the graphics context call patcherview_getjgraphics() on the patcherview arg
// use jcolumn_setcustompaint to set the message symbol for this method for a column

// the jdataview doesn't hold data. It just sends messages to an owning object to display it
// the messages may be cached for speed. The first level interface just defines a textual
// display. Eventually there will be a custom component for a row.

// sorting: columns can be textual (c_numeric == 0) or numeric or they can define a custom sort
// method by calling jcolumn_setcustomsort to a symbol. This symbol names a method that will be
// called to sort the data for this column. It is of the form:
// long myobject_sort(t_rowref a, t_rowref b) -- which will be passed two rowrefs. In addition,
// custom sort clients need to implement the sortdata message, which is passed a pointer to
// a t_privatesortrec. It needs to store this statically as it is sent before the custom sort message is
// received.
void jdataview_getcolumnmenuforcell(t_object *dv, t_symbol *colname, t_rowref rr, long *argc, t_atom **argv, char **enabled);
void jdataview_cellcolumnmenuresult(t_object *dv, t_symbol *colname, t_rowref rr, long result);

void jdataview_sortcolumn(t_object *x, t_symbol *colname, int fwd);
void jdataview_sort(t_object *x, t_symbol *colname, int fwd);
void jdataview_resort(t_object *x);
long jdataview_getsortcolumn(t_object *x);

// selection

void jdataview_selectcell(t_object *dv, t_symbol *colname, t_rowref rr);
void jdataview_selectrow(t_jdataview *x, t_rowref rr);
void jdataview_selectcolumn(t_jdataview *x, t_symbol *colname);
void jdataview_selectallrows(t_jdataview *x);

long jdataview_iscellselected(t_jdataview *x, t_symbol *colname, t_rowref rr);
long jdataview_isrowselected(t_jdataview *x, t_rowref rr);
long jdataview_iscolumnselected(t_jdataview *x, t_symbol *colname);

void jdataview_savecolumnwidths(t_object *dv, t_dictionary **d);
void jdataview_restorecolumnwidths(t_object *dv, t_dictionary *d);

void jdataview_updatefontpanelforclient(t_object *dv, long show);

// utilities for painting

void jdataview_redrawrow(t_object *dv, t_rowref rr);


#ifdef CUSTOMPAINT
void jdataview_getcellrect(t_jdataview *x, t_symbol *colname, t_rowref rr, t_rect *r);
t_max_err jdataview_jgraphics_from_paintcontext(t_jdataview *x, void *ctx, t_jgraphics **g);
#endif

// handle resizing

long jdataview_containersize(t_object *dv, double cw, double ch, double *width, double *height);

void jdataview_forcecellvisible(t_object *x, t_symbol *colname, t_rowref rr);


// messages to the owner

t_object *jdataview_getrowobject(t_object *dv, t_rowref rr);	// return object associated with the row, if any (used for dragging)

/*

-- "columncreated": notification of a column being created

void myobject_columncreated(t_myobject *x, t_symbol *colname);

-- "rowadded" / "rowdeleted": notification of a row being added / deleted

void myobject_rowadded(t_myobject *x, t_rowref rr);
void myobject_rowdeleted(t_myobject *x, t_rowref rr);

-- "sortstarted": notification of a sort starting (will get sort messages)

void myobject_sortstarted(t_myobject *x, t_symbol *colname, long direction);

-- "compare": sort the data according to column / direction, return 1 if r1 > r2, -1 if r2 > r1

long myobject_compare(t_myobject *x, t_symbol *colname, long direction, t_rowref r1, t_rowref r2);

-- "gettext": get string to show in a cell

void myobject_gettext(t_myobject *x, t_symbol *colname, t_rowref rr, char *text);

-- "editstarted": notification that editing is starting in a cell

void myobject_editstarted(t_myobject *x, t_symbol *colname, t_rowref rr);

-- "editentered": editing has finished and here is some new text for a cell

void myobject_editenter(t_myobject *x, t_symbol *colname, t_rowref rr, char *newtext);

// plus, a message specific to a button clicked in a cell (this allows for multiple buttons per column)

void myobject_buttonmessage(t_myobject *x, t_symbol *colname, t_rowref rr, t_symbol *msg);

// editing operations, "cutcell", "copycell", "pastecell", "clearcell"

void myobject_cutcell(t_myobject *x, t_symbol *colname, t_rowref rr);
void myobject_copycell(t_myobject *x, t_symbol *colname, t_rowref rr);
void myobject_pastecell(t_myobject *x, t_symbol *colname, t_rowref rr);
void myobject_clearcell(t_myobject *x, t_symbol *colname, t_rowref rr);

// "cutcolumn", "copycolumn", "pastecolumn", "clearcolumn"

void myobject_cutcolumn(t_myobject *x, t_symbol *colname);
void myobject_copycolumn(t_myobject *x, t_symbol *colname);
void myobject_pastecolumn(t_myobject *x, t_symbol *colname);
void myobject_clearcolumn(t_myobject *x, t_symbol *colname);

// "cutrow", "copyrow", "pasterow", "clearrow", "deleterow"

void myobject_cutrow(t_myobject *x, t_rowref rr);
void myobject_copyrow(t_myobject *x, t_rowref rr);
void myobject_pasterow(t_myobject *x, t_rowref rr);
void myobject_clearrow(t_myobject *x, t_rowref rr);
void myobject_deleterow(t_myobject *x, t_rowref rr);

// customization: an object can have a paintcell method instead of displaying text

void myobject_paintcell(t_myobject *x, t_symbol *colname, t_rowref rr, void *ctx);

// implementation notes:

JUCE refreshComponentForCell needs to have the ability to create a custom component given a
class name. How can that be done, with templates? 

Yes you can use template argument passed to new, i.e.,

template<class T>
blah<T>::blah
{
	foo (which could be a member of blah?) = new T;
}

*/

END_USING_C_LINKAGE

#endif // _JDATAVIEW_H_
